<?php

namespace Nece\Sdk\Coze\Api;

use Nece\Sdk\Coze\ApiAbstract;
use Nece\Sdk\Coze\Entity\EnterMessageList;

/**
 * 会话与消息
 *
 * @author gjw
 * @created 2025-04-23 14:01:42
 */
class Conversation extends ApiAbstract
{
    /**
     * 创建会话
     *
     * @author gjw
     * @created 2025-04-23 10:33:59
     *
     * @param string $bot_id 会话对应的智能体 ID。创建会话时指定智能体 ID，后续才能通过 查看会话列表 查看指定智能体 ID 对应的会话列表。
     * @param ?EnterMessageList $message_list 消息列表对象
     * @param array $meta_data 附加信息。kv对
     * @return array
     */
    public function create(string $bot_id = '', ?EnterMessageList $message_list = null, array $meta_data = [])
    {
        $api = '/v1/conversation/create';

        $params = array();
        if ($bot_id) {
            $params['bot_id'] = $bot_id;
        }

        if ($meta_data) {
            $params['meta_data'] = $meta_data;
        }

        if ($message_list) {
            $params['messages'] = $message_list->toArray();
        }

        return $this->post($api, $params);
    }

    /**
     * 更新会话名称
     *
     * @author gjw
     * @created 2025-08-05 11:30:58
     *
     * @param string $conversation_id 待更新的会话 ID。
     * @param string $name 更新后的会话名称，最多支持 100 个字符。
     * @return array
     */
    public function update($conversation_id, $name)
    {
        $api = '/v1/conversations/:conversation_id';
        $api = str_replace(':conversation_id', $conversation_id, $api);
        $params = array(
            'name' => $name,
        );

        return $this->post($api, $params, [], 'PUT');
    }

    /**
     * 删除会话
     *
     * @author gjw
     * @created 2025-08-05 11:33:04
     *
     * @param string $conversation_id 待删除的会话 ID。
     * @return array
     */
    public function delete($conversation_id)
    {
        $api = '/v1/conversations/:conversation_id';
        $api = str_replace(':conversation_id', $conversation_id, $api);
        return $this->post($api, [], [], 'DELETE');
    }

    /**
     * 查看会话信息
     *
     * @author gjw
     * @created 2025-04-23 10:33:44
     *
     * @param string $conversation_id Conversation ID，即会话的唯一标识。
     * @return array
     */
    public function retrieve(string $conversation_id)
    {
        $api = 'v1/conversation/retrieve';
        $query = array(
            'conversation_id' => $conversation_id,
        );

        return $this->get($api, $query);
    }

    /**
     * 查看会话列表
     *
     * @author gjw
     * @created 2025-04-23 10:39:07
     *
     * @param string $bot_id 智能体 ID
     * @param integer $page_num 页码，从 1 开始，默认为 1。
     * @param integer $page_size 每一页的数据条目个数，默认为 50，最大为 50。
     * @param string $sort_order 会话列表的排序方式
     * @param string $connector_id 发布渠道 ID
     * @return array
     */
    public function conversations(string $bot_id, int $page_num = 1, int $page_size = 50, string $sort_order = 'asc', string $connector_id = '')
    {
        $api = '/v1/conversations';

        $query = array(
            'bot_id' => $bot_id,
            'page_num' => $page_num,
            'page_size' => $page_size,
            'sort_order' => strtolower($sort_order),
        );

        if ($connector_id) {
            $query['connector_id'] = $connector_id;
        }

        return $this->get($api, $query);
    }

    /**
     * 清除上下文
     *
     * @author gjw
     * @created 2025-04-23 10:45:40
     *
     * @param string $conversation_id 待清除上下文的会话 ID。
     * @return array
     */
    public function clear(string $conversation_id)
    {
        $api = str_replace(':conversation_id', $conversation_id, '/v1/conversations/:conversation_id/clear');
        $params = array(
            'conversation_id' => $conversation_id,
        );

        return $this->post($api, $params);
    }

    /**
     * 创建消息
     *
     * @author gjw
     * @created 2025-04-23 10:48:33
     *
     * @param string $conversation_id 会话的唯一标识
     * @param string $role 发送这条消息的实体。取值：user：代表该条消息内容是用户发送的。assistant：代表该条消息内容是 Bot 发送的。
     * @param string $content 消息的内容，支持纯文本、多模态（文本、图片、文件混合输入）、卡片等多种类型的内容。
     * @param string $content_type 消息内容的类型，支持设置为：text：文本object_string：多模态内容，即文本和文件的组合、文本和图片的组合
     * @param array $meta_data 创建消息时的附加消息，通常用于封装一些业务相关的字段。获取消息时也会返回此附加消息。自定义键值对，应指定为 Map 对象格式。长度为 16 对键值对，其中键（key）的长度范围为 1～64 个字符，值（value）的长度范围为 1～512 个字符。
     * @return array
     */
    public function messageCreate(string $conversation_id, string $role, string $content, string $content_type, array $meta_data = [])
    {
        $api = '/v1/conversation/message/create';
        $query = array(
            'conversation_id' => $conversation_id,
        );

        $params = array(
            'role' => $role,
            'content' => $content,
            'content_type' => $content_type,
        );

        if ($meta_data) {
            $params['meta_data'] = $meta_data;
        }

        return $this->post($api, $params, $query);
    }

    /**
     * 查看消息列表
     *
     * @author gjw
     * @created 2025-04-23 10:59:30
     *
     * @param string $conversation_id 会话的唯一标识。
     * @param integer $limit 每次查询返回的数据量。默认为 50，取值范围为 1~50。
     * @param string $order 消息列表的排序方式。desc：（默认）按创建时间降序排序，最新的消息排序最前。asc：按创建时间升序排序，最早的消息排序最前。
     * @param string $chat_id 筛选指定 Chat ID 中的消息列表。发起对话接口 Response 中 Chat 事件的 data.id 字段即为 Chat ID。
     * @param string $before_id 查看指定位置之前的消息。默认为 0，表示不指定位置。如需向前翻页，则指定为返回结果中的 first_id。
     * @param string $after_id 查看指定位置之后的消息。默认为 0，表示不指定位置。如需向后翻页，则指定为返回结果中的 last_id。
     * @return array
     */
    public function messageList(string $conversation_id, int $limit = 50, string $order = 'desc', string $chat_id = '', string $before_id = '', string $after_id = '')
    {
        $api = '/v1/conversation/message/list';
        $query = array(
            'conversation_id' => $conversation_id,
        );

        $params = array(
            'order' => $order,
            'limit' => $limit,
        );

        if ($chat_id) {
            $params['chat_id'] = $chat_id;
        }
        if ($before_id) {
            $params['before_id'] = $before_id;
        }
        if ($after_id) {
            $params['after_id'] = $after_id;
        }
        return $this->post($api, $params, $query);
    }

    /**
     * 查看消息详情
     *
     * @author gjw
     * @created 2025-04-23 11:07:51
     *
     * @param string $conversation_id 会话的唯一标识。
     * @param string $message_id 消息的唯一标识。
     * @return array
     */
    public function messageRetrieve(string $conversation_id, string $message_id)
    {
        $api = '/v1/conversation/message/retrieve';
        $query = array(
            'conversation_id' => $conversation_id,
            'message_id' => $message_id,
        );

        return $this->get($api, $query);
    }

    /**
     * 修改消息
     *
     * @author gjw
     * @created 2025-04-23 11:11:29
     *
     * @param string $conversation_id 会话的唯一标识。
     * @param string $message_id 消息的唯一标识。
     * @param string $content 消息的内容，支持纯文本、多模态（文本、图片、文件混合输入）、卡片等多种类型的内容。
     * @param string $content_type 消息内容的类型。取值包括：text：文本object_string：多模态内容，即文本和文件的组合、文本和图片的组合
     * @param array $meta_data 创建消息时的附加消息，获取消息时也会返回此附加消息。自定义键值对，应指定为 Map 对象格式。长度为 16 对键值对，其中键（key）的长度范围为 1～64 个字符，值（value）的长度范围为 1～512 个字符。
     * @return array
     */
    public function messageModify(string $conversation_id, string $message_id, string $content = '', string $content_type = '', array $meta_data = [])
    {
        $api = '/v1/conversation/message/modify';
        $query = array(
            'conversation_id' => $conversation_id,
            'message_id' => $message_id,
        );

        $params = array();
        if ($content) {
            $params['content'] = $content;
        }
        if ($content_type) {
            $params['content_type'] = $content_type;
        }
        if ($meta_data) {
            $params['meta_data'] = $meta_data;
        }
        return $this->post($api, $params, $query);
    }

    /**
     * 删除消息
     *
     * @author gjw
     * @created 2025-04-23 11:13:20
     *
     * @param string $conversation_id
     * @param string $message_id
     * @return array
     */
    public function messageDelete(string $conversation_id, string $message_id)
    {
        $api = '/v1/conversation/message/delete';
        $query = array(
            'conversation_id' => $conversation_id,
            'message_id' => $message_id,
        );
        return $this->post($api, [], $query);
    }
}
